package org.jiuling.basics.wrapper;

import java.io.Serializable;
import java.util.*;
import java.util.function.*;

/**
 * Map包装类
 * @author 紫灵
 * @date 2024年08月21日 23时12分06秒
 */
public class MapWrapper<K,V> implements Map<K, V>, Iterable<Map.Entry<K, V>>, Serializable, Cloneable{

    /** 原始数据 */
    private final Map<K,V> raw;

    /**
     * 构造方法
     * @param raw 原始数据
     */
    public MapWrapper(Map<K, V> raw) {
        this.raw = raw;
    }

    /**
     * 构造方法
     * @param mapFactory 空的Map工厂
     */
    public MapWrapper(Supplier<Map<K, V>> mapFactory){
        this(mapFactory.get());
    }

    /**
     * 获取原始数据
     * @return 原始数据
     */
    public Map<K,V> getRaw(){
        return this.raw;
    }

    /**
     * 迭代器
     * @return 迭代器
     */
    @Override
    public Iterator<Entry<K, V>> iterator() {
        return this.entrySet().iterator();
    }

    /**
     * 获取Map数量
     * @return 数量
     */
    @Override
    public int size() {
        return this.raw.size();
    }

    /**
     * 为空
     * @return 是否为空
     */
    @Override
    public boolean isEmpty() {
        return this.raw.isEmpty();
    }

    /**
     * 键是否存在
     * @param key 键
     * @return 是否存在
     */
    @Override
    public boolean containsKey(Object key) {
        return this.raw.containsKey(key);
    }

    /**
     * 值是否存在
     * @param value 值
     * @return 是否存在
     */
    @Override
    public boolean containsValue(Object value) {
        return this.raw.containsValue(value);
    }

    /**
     * 获取值
     * @param key 键
     * @return 值
     */
    @Override
    public V get(Object key) {
        return this.raw.get(key);
    }

    /**
     * 添加键值对
     * @param key 键
     * @param value 值
     * @return 值
     */
    @Override
    public V put(K key, V value) {
        return this.raw.put(key, value);
    }

    /**
     * 移除键值对
     * @param key 键
     * @return 值
     */
    @Override
    public V remove(Object key) {
        return this.raw.remove(key);
    }

    /**
     * 添加所有键值对
     * @param map map对象
     */
    @Override
    public void putAll(Map<? extends K, ? extends V> map) {
        this.raw.putAll(map);
    }

    /**
     * 清除
     */
    @Override
    public void clear() {
        this.raw.clear();
    }

    /**
     * 键集合
     * @return 键集合
     */
    @Override
    public Set<K> keySet() {
        return this.raw.keySet();
    }

    /**
     * 值集合
     * @return 值集合
     */
    @Override
    public Collection<V> values() {
        return this.raw.values();
    }

    /**
     * 键值对集合
     * @return 键值对集合
     */
    @Override
    public Set<Entry<K, V>> entrySet() {
        return this.raw.entrySet();
    }

    @Override
    public void forEach(BiConsumer<? super K, ? super V> action) {
        this.raw.forEach(action);
    }

    @Override
    public void forEach(Consumer<? super Entry<K, V>> action) {
        this.raw.forEach((k,v)->action.accept((new AbstractMap.SimpleEntry<>(k, v))));
    }

    /**
     * 获取值，如果不存在则返回默认值
     * @param key 键
     * @param defaultValue 默认值
     * @return 值
     */
    @Override
    public V getOrDefault(Object key, V defaultValue) {
        return this.raw.getOrDefault(key, defaultValue);
    }

    /**
     * 替换全部键值对
     * @param function 函数
     */
    @Override
    public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
        this.raw.replaceAll(function);
    }

    /**
     * 如果键不存在，则添加键值对
     * @param key 键
     * @param value 值
     * @return 值
     */
    @Override
    public V putIfAbsent(K key, V value) {
        return this.raw.putIfAbsent(key, value);
    }

    /**
     * 移除键值对
     * @param key 键
     * @param value 值
     * @return 是否移除
     */
    @Override
    public boolean remove(Object key, Object value) {
        return this.raw.remove(key, value);
    }

    /**
     * 替换键值对
     * @param key 键
     * @param oldValue 旧值
     * @param newValue 新值
     * @return 是否替换
     */
    @Override
    public boolean replace(K key, V oldValue, V newValue) {
        return this.raw.replace(key, oldValue, newValue);
    }

    /**
     * 替换键值对
     * @param key 键
     * @param value 值
     * @return 值
     */
    @Override
    public V replace(K key, V value) {
        return this.raw.replace(key, value);
    }

    /**
     * 计算键值对
     * @param key 键
     * @param mappingFunction 映射函数
     * @return 值
     */
    @Override
    public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
        return this.raw.computeIfAbsent(key, mappingFunction);
    }

    /**
     * 计算键值对
     * @param key 键
     * @param remappingFunction 重映射函数
     * @return 值
     */
    @Override
    public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
        return this.raw.computeIfPresent(key, remappingFunction);
    }

    /**
     * 计算键值对
     * @param key 键
     * @param remappingFunction 重映射函数
     * @return 值
     */
    @Override
    public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
        return this.raw.compute(key, remappingFunction);
    }

    /**
     * 合并键值对
     * @param key 键
     * @param value 值
     * @param remappingFunction 重映射函数
     * @return 值
     */
    @Override
    public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
        return this.raw.merge(key, value, remappingFunction);
    }

}
